/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = t_rtsp_analyze_header.c                            */
/*  NOTE      =                                                    */
/*  DATE      = 2016/02/01 by songbb                               */
/*******************************************************************/

#include <CUnit/Basic.h>
#include <stdlib.h>

#include "frcomm.h"
#include "frmem.h"

#include "../../../src/module/rtsp/config.h"
#include <rtsp/rtsp_core.h>
#include <rtsp/rtsp_header.h>
#include <rtsp/rtsp_comm.h>
#include <rtsp/rtsp_packet.h>

extern void __rtsp_destroy_packet(L7_rtsp_packet **pp_st_rtsp_packet);

static int __suite_init(void)
{
    return 0;
}

static int __suite_cleanup(void)
{
    return 0;
}

/**
 * 正确的请求头
 * OPTIONS
 */
static void __case1(void)
{
    char *p_payload = (char *) "OPTIONS rtsp://192.168.24.59:554 RTSP/1.0\r\n"
            "CSeq: 2\r\n"
            "User-Agent: LibVLC/2.2.1 (LIVE555 Streaming Media v2014.07.25)\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "OPTIONS");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_OPTIONS);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * DESCRIBE
 */
static void __case2(void)
{
    char *p_payload = (char *) "DESCRIBE rtsp://server.example.com/fizzle/foo RTSP/1.0\r\n"
            "CSeq: 312\r\n"
            "Accept: application/sdp, application/rtsl, application/mheg\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "DESCRIBE");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_DESCRIBE);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * ANNOUNCE
 */
static void __case3(void)
{
    char *p_payload = (char *) "ANNOUNCE rtsp://server.example.com/fizzle/foo RTSP/1.0\r\n"
            "CSeq: 312\r\n"
            "Date: 23 Jan 1997 15:35:06 GMT\r\n"
            "Session: 47112344\r\n"
            "Content-Type: application/sdp\r\n"
            "Content-Length: 332\r\n"
            "\r\n"
            "v=0\r\n"
            "o=mhandley 2890844526 2890845468 IN IP4 126.16.64.4\r\n"
            "s=SDP Seminar\r\n"
            "i=A Seminar on the session description protocol\r\n"
            "u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps\r\n"
            "e=mjh@isi.edu (Mark Handley)\r\n"
            "c=IN IP4 224.2.17.12/127\r\n"
            "t=2873397496 2873404696\r\n"
            "a=recvonly\r\n"
            "m=audio 3456 RTP/AVP 0\r\n"
            "m=video 2232 RTP/AVP 31";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;
    int i_content_len = 0;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), &i_content_len);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "ANNOUNCE");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_ANNOUNCE);
    CU_ASSERT_EQUAL(i_content_len, 332);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * SETUP
 */
static void __case4(void)
{
    char *p_payload = (char *) "SETUP rtsp://server.com/foo/bar/baz.rm RTSP/1.0\r\n"
            "CSeq: 302\r\n"
            "Require: funky-feature\r\n"
            "Funky-Parameter: funkystuff\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "SETUP");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_SETUP);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * PLAY
 */
static void __case5(void)
{
    char *p_payload = (char *) "PLAY rtsp://audio.example.com/twister.en RTSP/1.0\r\n"
            "CSeq: 833\r\n"
            "Session: 12345678\r\n"
            "Range: smpte=0:10:20-;time=19970123T153600Z\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "PLAY");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_PLAY);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * PAUSE
 */
static void __case6(void)
{
    char *p_payload = (char *) "PAUSE rtsp://example.com/fizzle/foo RTSP/1.0\r\n"
            "CSeq: 834\r\n"
            "Session: 12345678\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "PAUSE");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_PAUSE);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * TEARDOWN
 */
static void __case7(void)
{
    char *p_payload = (char *) "TEARDOWN rtsp://example.com/fizzle/foo RTSP/1.0\r\n"
            "CSeq: 892\r\n"
            "Session: 12345678\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "TEARDOWN");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_TEARDOWN);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * GET_PARAMETER
 */
static void __case8(void)
{
    char *p_payload = (char *) "GET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0\r\n"
            "CSeq: 431\r\n"
            "Content-Type: text/parameters\r\n"
            "Session: 12345678\r\n"
            "Content-Length: 15\r\n"
            "\r\n"
            "packets_received\r\n"
            "jitter\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;
    int i_content_len = 0;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), &i_content_len);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "GET_PARAMETER");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_GET_PARAMETER);
    CU_ASSERT_EQUAL(i_content_len, 15);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * SET_PARAMETER
 */
static void __case9(void)
{
    char *p_payload = (char *) "SET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0\r\n"
            "CSeq: 421\r\n"
            "Content-length: 20\r\n"
            "Content-type: text/parameters\r\n"
            "\r\n"
            "barparam: barstuff\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;
    int i_content_len = 0;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), &i_content_len);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "SET_PARAMETER");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_SET_PARAMETER);
    CU_ASSERT_EQUAL(i_content_len, 20);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * REDIRECT
 */
static void __case10(void)
{
    char *p_payload = (char *) "REDIRECT rtsp://example.com/fizzle/foo RTSP/1.0\r\n"
            "CSeq: 732\r\n"
            "Location: rtsp://bigserver.com:8001\r\n"
            "Range: clock=19960213T143205Z-\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "REDIRECT");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_REDIRECT);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 正确的请求头
 * RECORD
 */
static void __case11(void)
{
    char *p_payload = (char *) "RECORD rtsp://server.example.com/meeting RTSP/1.0\r\n"
            "CSeq: 93\r\n"
            "Session: 50887676\r\n"
            "Range: clock=19961110T1925-19961110T2015\r\n\r\n";

    int i_ret;
    int i_is_req = FR_NO;
    L7_rtsp_packet *p_st_rtsp_packet = NULL;
    if ((p_st_rtsp_packet = (L7_rtsp_packet *) frmalloc(sizeof(L7_rtsp_packet))) == NULL)
        return;
    memset(p_st_rtsp_packet, 0x00, sizeof(L7_rtsp_packet));
    if (rtsp_init_packet(p_st_rtsp_packet) != FR_SUCC)
        return;

    i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), &i_is_req, &(p_st_rtsp_packet->p_req_method), &(p_st_rtsp_packet->em_req_method), NULL);

    CU_ASSERT_EQUAL(i_ret, FR_SUCC);
    CU_ASSERT_EQUAL(i_is_req, FR_YES);
    CU_ASSERT_STRING_EQUAL(p_st_rtsp_packet->p_req_method, "RECORD");
    CU_ASSERT_EQUAL(p_st_rtsp_packet->em_req_method, RTSP_METHOD_TYPE_RECORD);

    __rtsp_destroy_packet(&p_st_rtsp_packet);
    CU_ASSERT_PTR_NULL(p_st_rtsp_packet);
}

/**
 * 错误的请求头
 */
static void __case12(void)
{
    char *p_payload = (char *) "OP rtsp://192.168.24.59:554 RTSP/1.0\r\n"
            "CSeq: 2\r\n"
            "User-Agent: LibVLC/2.2.1 (LIVE555 Streaming Media v2014.07.25)\r\n\r\n";

    int i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), NULL, NULL, NULL, NULL);
    CU_ASSERT_EQUAL(i_ret, FR_FAIL);
}

/**
 * 错误的请求头
 */
static void __case13(void)
{
    char *p_payload = (char *) "OPTIONS rtsp://192.168.24.59:554 RTSP/1.\r\n"
            "CSeq: 2\r\n"
            "User-Agent: LibVLC/2.2.1 (LIVE555 Streaming Media v2014.07.25)\r\n\r\n";

    int i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), NULL, NULL, NULL, NULL);
    CU_ASSERT_EQUAL(i_ret, FR_FAIL);
}

/**
 * 错误的请求头
 */
static void __case14(void)
{
    char *p_payload = (char *) "OPTIONS rtsp://192.168.24.59:554 TSP/1.0\r\n"
            "CSeq: 2\r\n"
            "User-Agent: LibVLC/2.2.1 (LIVE555 Streaming Media v2014.07.25)\r\n\r\n";

    int i_ret = rtsp_analyze_header(p_payload, strlen(p_payload), NULL, NULL, NULL, NULL);
    CU_ASSERT_EQUAL(i_ret, FR_FAIL);
}

int add_suite_rtsp_analyze_header(void)
{
    CU_pSuite pSuite = NULL;

    if ((pSuite = CU_add_suite(MODULE_NAME" rtsp_analyze_header()", __suite_init, __suite_cleanup)) == NULL)
        return FR_FAIL;

    if (CU_add_test(pSuite, "case1", __case1) == NULL ||
        CU_add_test(pSuite, "case2", __case2) == NULL ||
        CU_add_test(pSuite, "case3", __case3) == NULL ||
        CU_add_test(pSuite, "case4", __case4) == NULL ||
        CU_add_test(pSuite, "case5", __case5) == NULL ||
        CU_add_test(pSuite, "case6", __case6) == NULL ||
        CU_add_test(pSuite, "case7", __case7) == NULL ||
        CU_add_test(pSuite, "case8", __case8) == NULL ||
        CU_add_test(pSuite, "case9", __case9) == NULL ||
        CU_add_test(pSuite, "case10", __case10) == NULL ||
        CU_add_test(pSuite, "case11", __case11) == NULL ||
        CU_add_test(pSuite, "case12", __case12) == NULL ||
        CU_add_test(pSuite, "case13", __case13) == NULL ||
        CU_add_test(pSuite, "case14", __case14) == NULL)
        return FR_FAIL;

    return FR_SUCC;
}
